package controllers

import (
	"library-system/config"
	"library-system/models"
	"library-system/utils"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
)

// 正确定义借阅控制器结构体
type BorrowController struct{}

// 借书方法（注意首字母大写）
func (bc *BorrowController) BorrowBook(c *gin.Context) {
	claims := c.MustGet("claims").(*utils.Claims)
	var borrowReq struct {
		BookID uint `json:"book_id" binding:"required"`
	}

	if err := c.ShouldBindJSON(&borrowReq); err != nil {
		utils.Error(c, utils.ErrorCode, "请求参数有误")
		return
	}

	tx := config.DB.Begin()

	var book models.Book
	if err := tx.First(&book, borrowReq.BookID).Error; err != nil {
		tx.Rollback()
		utils.Error(c, utils.ErrorCode, "图书不存在")
		return
	}

	if book.Stock < 1 {
		tx.Rollback()
		utils.Error(c, utils.ErrorCode, "库存不足")
		return
	}

	record := models.BorrowRecord{
		UserID:     claims.UserID,
		BookID:     borrowReq.BookID,
		BorrowDate: time.Now(),
		Status:     "borrowed",
	}

	if err := tx.Create(&record).Error; err != nil {
		tx.Rollback()
		utils.Error(c, utils.ErrorCode, "请求参数有误")
		return
	}

	if err := tx.Model(&book).Update("stock", book.Stock-1).Error; err != nil {
		tx.Rollback()
		utils.Error(c, utils.ErrorCode, "借阅书籍失败")
		return
	}

	tx.Commit()
	utils.Success(c, "成功借阅书籍", gin.H{"data": record})
}

// 还书方法（同样注意首字母大写）
func (bc *BorrowController) ReturnBook(c *gin.Context) {
	recordID := c.Param("id")
	claims := c.MustGet("claims").(*utils.Claims)

	tx := config.DB.Begin()

	var record models.BorrowRecord
	if err := tx.First(&record, recordID).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusNotFound, gin.H{"error": "借阅记录不存在"})
		return
	}

	if record.UserID != claims.UserID && claims.Role != "admin" {
		tx.Rollback()
		c.JSON(http.StatusForbidden, gin.H{"error": "无操作权限"})
		return
	}

	now := time.Now()
	record.ReturnDate = &now
	record.Status = "returned"

	if err := tx.Save(&record).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	var book models.Book
	if err := tx.First(&book, record.BookID).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	if err := tx.Model(&book).Update("stock", book.Stock+1).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, record)
}
